package com.lzx.iteam.util;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

/**
 * Created with IntelliJ IDEA.
 * **********************************
 * User: zhangshuai
 * Date: 2016年 05月 23日
 * Time: 下午12:22
 *
 * @QQ : 1234567890
 * **********************************
 */
public class WeekUtil {

    // 获取当前时间所在月的周数
    public static int getWeekOfMonth(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        return c.get(Calendar.WEEK_OF_MONTH);
    }
    // 获取当前时间所在年的周数
    public static int getWeekOfYearToday() {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setMinimalDaysInFirstWeek(7);
        Date today = new Date();
        c.setTime(today);

        return c.get(Calendar.WEEK_OF_YEAR) - 1;
    }

    // 获取一个日期所在年的周数
    public static int getWeekOfYear(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setMinimalDaysInFirstWeek(7);
        c.setTime(date);

        return c.get(Calendar.WEEK_OF_YEAR) - 1;
    }

    // 获取一个日期所在年的周数
    public static int getDateWeekOfYear() {
        int sum = 0;
        int leap = 0;
        Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH) + 1;
        int day = c.get(Calendar.DATE);
        switch (month) /* 先计算某月以前月份的总天数 */
        {
            case 1:
                sum = 0;
                break;
            case 2:
                sum = 31;
                break;
            case 3:
                sum = 59;
                break;
            case 4:
                sum = 90;
                break;
            case 5:
                sum = 120;
                break;
            case 6:
                sum = 151;
                break;
            case 7:
                sum = 181;
                break;
            case 8:
                sum = 212;
                break;
            case 9:
                sum = 243;
                break;
            case 10:
                sum = 273;
                break;
            case 11:
                sum = 304;
                break;
            case 12:
                sum = 334;
                break;
            default:
                System.out.println("data error");
                break;
        }
        sum = sum + day; /* 再加上某天的天数 */
        if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))/* 判断是不是闰年 */
            leap = 1;
        else
            leap = 0;
        if (leap == 1 && month > 2)/* 如果是闰年且月份大于2,总天数应该加一天 */
            sum++;
        int dayOfWeek = WeekUtil.getWeekdayOfMonth(year, 1);
        if (sum + dayOfWeek - 8 <= 0){
            return 0;
        }else{
            int extra = (sum + dayOfWeek - 8)%7;
            if (extra == 0){
                return (sum + dayOfWeek - 8)/7;
            }else{
                return (sum + dayOfWeek - 8)/7 + 1;
            }
        }
    }

    // 获取一个日期所在年的周数
    public static int getDateWeekOfYear(int year,int month,int day) {
        int sum = 0;
        int leap = 0;
        Calendar c = Calendar.getInstance();
        switch (month) /* 先计算某月以前月份的总天数 */
        {
            case 1:
                sum = 0;
                break;
            case 2:
                sum = 31;
                break;
            case 3:
                sum = 59;
                break;
            case 4:
                sum = 90;
                break;
            case 5:
                sum = 120;
                break;
            case 6:
                sum = 151;
                break;
            case 7:
                sum = 181;
                break;
            case 8:
                sum = 212;
                break;
            case 9:
                sum = 243;
                break;
            case 10:
                sum = 273;
                break;
            case 11:
                sum = 304;
                break;
            case 12:
                sum = 334;
                break;
            default:
                System.out.println("data error");
                break;
        }
        sum = sum + day; /* 再加上某天的天数 */
        if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))/* 判断是不是闰年 */
            leap = 1;
        else
            leap = 0;
        if (leap == 1 && month > 2)/* 如果是闰年且月份大于2,总天数应该加一天 */
            sum++;
        int dayOfWeek = WeekUtil.getWeekdayOfMonth(year, 1);
        if (sum + dayOfWeek - 8 <= 0){
            return 0;
        }else{
            int extra = (sum + dayOfWeek - 8)%7;
            if (extra == 0){
                return (sum + dayOfWeek - 8)/7;
            }else{
                return (sum + dayOfWeek - 8)/7 + 1;
            }
        }
    }

    // 获取当前时间所在年的最大周数
    public static int getMaxWeekNumOfYear(int year) {
        Calendar c = new GregorianCalendar();
        c.set(year, Calendar.DECEMBER, 31, 23, 59, 59);

        return getWeekOfYear(c.getTime());
    }

    // 获取某年的第几周的开始日期
    public static Date getFirstDayOfWeek(int year, int week) {
        Calendar c = new GregorianCalendar();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, Calendar.JANUARY);
        c.set(Calendar.DATE, 1);

        Calendar cal = (GregorianCalendar) c.clone();
        cal.add(Calendar.DATE, week * 7);

        return getFirstDayOfWeek(cal.getTime());
    }

    // 获取某年的第几周的结束日期
    public static Date getLastDayOfWeek(int year, int week) {
        Calendar c = new GregorianCalendar();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, Calendar.JANUARY);
        c.set(Calendar.DATE, 1);

        Calendar cal = (GregorianCalendar) c.clone();
        cal.add(Calendar.DATE, week * 7);

        return getLastDayOfWeek(cal.getTime());
    }

    // 获取当前时间所在周的开始日期
    public static Date getFirstDayOfWeek(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek()); // Monday
        return c.getTime();
    }

    // 获取当前时间所在周的结束日期
    public static Date getLastDayOfWeek(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 4); // Sunday
        return c.getTime();
    }

    //某年中的某月的第一天是星期几
    public static int getWeekdayOfMonth(int year, int month){
        Calendar cal = Calendar.getInstance();
        cal.set(year, month-1, 1);
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;
        return dayOfWeek;
    }

    /**
     * 获取某年某月第几周的星期一（周计数为月中的周计数）
     * @param year
     * @param month
     * @param weekCount
     * @return
     */
    public static Date getWeekDateByCount(int year,int month,int weekCount){

        Calendar cal=Calendar.getInstance(Locale.CHINA);
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month-1);
        cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, weekCount);
        //int day=cal.get(Calendar.DATE);
        //return getDateWeekOfYear(year,month,day);
        return cal.getTime();
    }

    public static void main() {
        int year = 2015;
        int week = 27;

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date today = new Date();
        Calendar c = new GregorianCalendar();
        c.setTime(today);

        System.out.println("当前时间:current date = " + sdf.format(today));
        System.out.println("当前第几周:getWeekOfYear = " + getWeekOfYear(today));
        System.out.println("年度总周数:getMaxWeekNumOfYear = " + getMaxWeekNumOfYear(year));
        System.out.println("本周第一天:getFirstDayOfWeek = " + sdf.format(getFirstDayOfWeek(year, week)));
        System.out.println("本周最后一天:getLastDayOfWeek = " + sdf.format(getLastDayOfWeek(year, week)));
        System.out.println("本周第一天:getFirstDayOfWeek = " + sdf.format(getFirstDayOfWeek(today)));
        System.out.println("本周最后一天:getLastDayOfWeek = " + sdf.format(getLastDayOfWeek(today)));
    }
}
